home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH10 / SRC / SURFACE2.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1996-05-02  |  16.3 KB  |  558 lines

  1. VERSION 4.00
  2. Begin VB.Form SurfaceForm 
  3.    Appearance      =   0  'Flat
  4.    BackColor       =   &H00C0C0C0&
  5.    Caption         =   "Surfaces"
  6.    ClientHeight    =   5700
  7.    ClientLeft      =   300
  8.    ClientTop       =   855
  9.    ClientWidth     =   9090
  10.    BeginProperty Font 
  11.       name            =   "MS Sans Serif"
  12.       charset         =   1
  13.       weight          =   700
  14.       size            =   8.25
  15.       underline       =   0   'False
  16.       italic          =   0   'False
  17.       strikethrough   =   0   'False
  18.    EndProperty
  19.    ForeColor       =   &H80000008&
  20.    Height          =   6390
  21.    KeyPreview      =   -1  'True
  22.    Left            =   240
  23.    LinkTopic       =   "Form1"
  24.    ScaleHeight     =   5700
  25.    ScaleWidth      =   9090
  26.    Top             =   225
  27.    Width           =   9210
  28.    Begin VB.CheckBox ShowAxesCheck 
  29.       Caption         =   "Show Axes"
  30.       Height          =   255
  31.       Left            =   7080
  32.       TabIndex        =   16
  33.       Top             =   3960
  34.       Width           =   2055
  35.    End
  36.    Begin VB.OptionButton Choice 
  37.       Caption         =   "Saddle"
  38.       Height          =   255
  39.       Index           =   8
  40.       Left            =   7080
  41.       TabIndex        =   15
  42.       Top             =   2880
  43.       Width           =   2055
  44.    End
  45.    Begin VB.OptionButton Choice 
  46.       Caption         =   "Cone"
  47.       Height          =   255
  48.       Index           =   7
  49.       Left            =   7080
  50.       TabIndex        =   14
  51.       Top             =   2520
  52.       Width           =   2055
  53.    End
  54.    Begin VB.OptionButton Choice 
  55.       Caption         =   "Holes"
  56.       Height          =   255
  57.       Index           =   6
  58.       Left            =   7080
  59.       TabIndex        =   13
  60.       Top             =   2160
  61.       Width           =   2055
  62.    End
  63.    Begin VB.TextBox PhiText 
  64.       Height          =   285
  65.       Left            =   3600
  66.       TabIndex        =   12
  67.       Text            =   "0.1570"
  68.       Top             =   5400
  69.       Width           =   855
  70.    End
  71.    Begin VB.TextBox ThetaText 
  72.       Height          =   285
  73.       Left            =   2040
  74.       TabIndex        =   10
  75.       Text            =   "0.6283"
  76.       Top             =   5400
  77.       Width           =   855
  78.    End
  79.    Begin VB.TextBox RText 
  80.       Height          =   285
  81.       Left            =   480
  82.       TabIndex        =   8
  83.       Text            =   "10"
  84.       Top             =   5400
  85.       Width           =   855
  86.    End
  87.    Begin VB.OptionButton Choice 
  88.       Caption         =   "Hemisphere"
  89.       Height          =   255
  90.       Index           =   5
  91.       Left            =   7080
  92.       TabIndex        =   7
  93.       Top             =   1800
  94.       Width           =   2055
  95.    End
  96.    Begin VB.OptionButton Choice 
  97.       Caption         =   "Randomized Ridges"
  98.       Height          =   255
  99.       Index           =   4
  100.       Left            =   7080
  101.       TabIndex        =   6
  102.       Top             =   1440
  103.       Width           =   2055
  104.    End
  105.    Begin VB.OptionButton Choice 
  106.       Caption         =   "Ridges"
  107.       Height          =   255
  108.       Index           =   3
  109.       Left            =   7080
  110.       TabIndex        =   5
  111.       Top             =   1080
  112.       Width           =   2055
  113.    End
  114.    Begin VB.OptionButton Choice 
  115.       Caption         =   "Bowl"
  116.       Height          =   255
  117.       Index           =   2
  118.       Left            =   7080
  119.       TabIndex        =   4
  120.       Top             =   720
  121.       Width           =   2055
  122.    End
  123.    Begin VB.OptionButton Choice 
  124.       Caption         =   "Mounds"
  125.       Height          =   255
  126.       Index           =   1
  127.       Left            =   7080
  128.       TabIndex        =   3
  129.       Top             =   360
  130.       Width           =   2055
  131.    End
  132.    Begin VB.OptionButton Choice 
  133.       Caption         =   "Splash"
  134.       Height          =   255
  135.       Index           =   0
  136.       Left            =   7080
  137.       TabIndex        =   2
  138.       Top             =   0
  139.       Value           =   -1  'True
  140.       Width           =   2055
  141.    End
  142.    Begin VB.PictureBox Pict 
  143.       AutoRedraw      =   -1  'True
  144.       Height          =   5295
  145.       Left            =   0
  146.       ScaleHeight     =   349
  147.       ScaleMode       =   3  'Pixel
  148.       ScaleWidth      =   461
  149.       TabIndex        =   0
  150.       Top             =   0
  151.       Width           =   6975
  152.    End
  153.    Begin MSComDlg.CommonDialog LoadDialog 
  154.       Left            =   7080
  155.       Top             =   4560
  156.       _version        =   65536
  157.       _extentx        =   847
  158.       _extenty        =   847
  159.       _stockprops     =   0
  160.       cancelerror     =   -1  'True
  161.    End
  162.    Begin VB.Label Label1 
  163.       Caption         =   "Phi"
  164.       Height          =   255
  165.       Index           =   2
  166.       Left            =   3240
  167.       TabIndex        =   11
  168.       Top             =   5400
  169.       Width           =   375
  170.    End
  171.    Begin VB.Label Label1 
  172.       Caption         =   "Theta"
  173.       Height          =   255
  174.       Index           =   1
  175.       Left            =   1440
  176.       TabIndex        =   9
  177.       Top             =   5400
  178.       Width           =   495
  179.    End
  180.    Begin VB.Label Label1 
  181.       Caption         =   "R"
  182.       Height          =   255
  183.       Index           =   0
  184.       Left            =   240
  185.       TabIndex        =   1
  186.       Top             =   5400
  187.       Width           =   255
  188.    End
  189.    Begin VB.Menu mnuFile 
  190.       Caption         =   "&File"
  191.       Begin VB.Menu mnuFileLoad 
  192.          Caption         =   "&Load..."
  193.          Shortcut        =   ^L
  194.       End
  195.       Begin VB.Menu mnuFileSaveAs 
  196.          Caption         =   "&Save As..."
  197.          Shortcut        =   ^A
  198.       End
  199.       Begin VB.Menu mnuFileSep 
  200.          Caption         =   "-"
  201.       End
  202.       Begin VB.Menu mnuFileExit 
  203.          Caption         =   "E&xit"
  204.       End
  205.    End
  206. Attribute VB_Name = "SurfaceForm"
  207. Attribute VB_Creatable = False
  208. Attribute VB_Exposed = False
  209. Option Explicit
  210. ' Location of viewing eye.
  211. Dim EyeR As Single
  212. Dim EyeTheta As Single
  213. Dim EyePhi As Single
  214. Const Dtheta = PI / 20
  215. Const Dphi = PI / 20
  216. Const Dr = 1
  217. ' Location of focus point.
  218. Const FocusX = 0#
  219. Const FocusY = 0#
  220. Const FocusZ = 0#
  221. Dim Projector(1 To 4, 1 To 4) As Single
  222. Dim ThePicture As ObjPicture
  223. Dim ShowingParameters As Boolean
  224. Dim ChoiceNum As Integer
  225. ' ************************************************
  226. ' Return the surface's value at this point.
  227. ' ************************************************
  228. Function SurfaceValue(x As Single, z As Single) As Single
  229. Const Xmin = -5
  230. Const Amp = 0.25
  231. Const Per = 2 * PI / 4
  232. Const Amp2 = 1
  233. Const Per2 = 2 * PI / 16
  234. Const Amp3 = 2
  235. Const R2 = 16.81
  236. Dim D As Single
  237. Dim x1 As Single
  238. Dim z1 As Single
  239. Dim x2 As Single
  240. Dim z2 As Single
  241. Dim y As Single
  242.     Select Case ChoiceNum
  243.         Case 0  ' Splash.
  244.             D = Sqr(x * x + z * z)
  245.             y = Amp * Cos(3 * D)
  246.         
  247.         Case 1  ' Mounds.
  248.             y = Amp * (Cos(Per * x) + Cos(Per * z))
  249.         
  250.         Case 2  ' Bowl.
  251.             y = 0.2 * (x * x + z * z) - 5#
  252.         
  253.         Case 3  ' Ridges.
  254.             y = Amp2 * Cos(Per2 * x) + Amp3 * Cos(Per * z) / (Abs(z) / 3 + 1)
  255.         Case 4  ' Random ridges.
  256.             y = Amp2 * Cos(Per2 * x) + Amp3 * Cos(Per * z) / (Abs(z) / 3 + 1) + Amp * Rnd / 2
  257.         Case 5  ' Hemisphere.
  258.             D = x * x + z * z
  259.             If D >= R2 Then
  260.                 y = 0
  261.             Else
  262.                 y = Sqr(R2 - D)
  263.             End If
  264.         
  265.         Case 6  ' Holes.
  266.             x1 = (x + Xmin / 2)
  267.             z1 = (z + Xmin / 2)
  268.             x2 = (x - Xmin / 2)
  269.             z2 = (z - Xmin / 2)
  270.             y = Amp3 - _
  271.         1 / (x1 * x1 + z1 * z1 + 0.1) - _
  272.         1 / (x2 * x2 + z1 * z1 + 0.1) - _
  273.         1 / (x1 * x1 + z2 * z2 + 0.1) - _
  274.         1 / (x2 * x2 + z2 * z2 + 0.1)
  275.         Case 7  ' Cone.
  276.             D = 2 * (Amp3 - Sqr(x * x + z * z))
  277.             If D < -Amp3 Then D = -Amp3
  278.             y = D
  279.         Case 8  ' Saddle.
  280.             y = (x * x - z * z) / 10
  281.         
  282.     End Select
  283.     SurfaceValue = y
  284. End Function
  285. ' *******************************************************
  286. ' Rotate the points in the cube and draw the cube.
  287. ' *******************************************************
  288. Private Sub DrawData(pic As Object)
  289. Dim x As Single
  290. Dim y As Single
  291. Dim z As Single
  292. Dim S(1 To 4, 1 To 4) As Single
  293. Dim t(1 To 4, 1 To 4) As Single
  294. Dim ST(1 To 4, 1 To 4) As Single
  295. Dim PST(1 To 4, 1 To 4) As Single
  296.     MousePointer = vbHourglass
  297.     Refresh
  298.     ' Prevent overflow errors when drawing lines
  299.     ' too far out of bounds.
  300.     On Error Resume Next
  301.     ' Scale and translate so it looks OK in pixels.
  302.     m3Scale S, 35, -35, 1
  303.     m3Translate t, 230, 175, 0
  304.     m3MatMultiplyFull ST, S, t
  305.     m3MatMultiplyFull PST, Projector, ST
  306.     ' Transform the points.
  307.     ThePicture.ApplyFull PST
  308.     ' Display the data.
  309.     pic.Cls
  310.     ThePicture.Draw pic, EyeR
  311.     pic.Refresh
  312.     ' Display the viewnig parameters.
  313.     ShowViewingParameters
  314.     MousePointer = vbDefault
  315. End Sub
  316. Sub ShowViewingParameters()
  317.     ShowingParameters = True
  318.     RText.Text = Format$(EyeR, "0.0000")
  319.     ThetaText.Text = Format$(EyeTheta, "0.0000")
  320.     PhiText.Text = Format$(EyePhi, "0.0000")
  321.     RText.Refresh
  322.     ThetaText.Refresh
  323.     PhiText.Refresh
  324.     ShowingParameters = False
  325. End Sub
  326. Private Sub Choice_Click(Index As Integer)
  327.     ChoiceNum = Index
  328.     CreateData (ShowAxesCheck.value = vbChecked)
  329.     DrawData Pict
  330.     Pict.SetFocus
  331. End Sub
  332. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  333.     Select Case KeyCode
  334.         Case vbKeyLeft
  335.             EyeTheta = EyeTheta - Dtheta
  336.         
  337.         Case vbKeyRight
  338.             EyeTheta = EyeTheta + Dtheta
  339.         
  340.         Case vbKeyUp
  341.             EyePhi = EyePhi - Dphi
  342.         
  343.         Case vbKeyDown
  344.             EyePhi = EyePhi + Dphi
  345.                 
  346.         Case Else
  347.             Exit Sub
  348.     End Select
  349.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  350.     DrawData Pict
  351. End Sub
  352. Private Sub Form_KeyPress(KeyAscii As Integer)
  353.     Select Case KeyAscii
  354.         Case Asc("+")
  355.             EyeR = EyeR + Dr
  356.         
  357.         Case Asc("-")
  358.             EyeR = EyeR - Dr
  359.         
  360.         Case Else
  361.             Exit Sub
  362.     End Select
  363.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  364.     DrawData Pict
  365. End Sub
  366. Private Sub Form_Load()
  367.     ' Initialize the eye position.
  368.     EyeR = 10
  369.     EyeTheta = PI * 0.2
  370.     EyePhi = PI * 0.1
  371.     ' Initialize the projection transformation.
  372.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  373.     ' Create the data.
  374.     CreateData (ShowAxesCheck.value = vbChecked)
  375.     ' Project and draw the data.
  376.     Me.Show
  377.     DrawData Pict
  378. End Sub
  379. ' ************************************************
  380. ' Create the surface.
  381. ' ************************************************
  382. Sub CreateData(show_axes As Boolean)
  383. Const Xmin = -5     ' The area the grid should cover.
  384. Const Zmin = -5
  385. Const Xmax = -Xmin
  386. Const Zmax = -Zmin
  387. Const GapX = 0.5    ' Distance between curves parallel
  388. Const GapZ = 0.5    '   to the X and Z axes.
  389. Const Dx = 0.1      ' Distance between points along
  390. Const Dz = 0.1      '   the curves.
  391. Dim refined As ObjPicture   ' The refined grid.
  392. Dim pline As ObjPolyline    ' A polyline in the grid.
  393. Dim axis As ObjPolyline
  394. Dim i As Integer
  395. Dim j As Integer
  396. Dim x As Single
  397. Dim y As Single
  398. Dim z As Single
  399. Dim x1 As Single
  400. Dim y1 As Single
  401. Dim z1 As Single
  402.     MousePointer = vbHourglass
  403.     Refresh
  404.     Set ThePicture = New ObjPicture
  405.     Set refined = New ObjPicture
  406.     ThePicture.objects.Add refined
  407.     If show_axes Then
  408.         Set axis = New ObjPolyline
  409.         ThePicture.objects.Add axis
  410.         axis.AddSegment 0, 0, 0, 5.5, 0, 0
  411.         axis.AddSegment 0, 0, 0, 0, 3, 0
  412.         axis.AddSegment 0, 0, 0, 0, 0, 5.5
  413.     End If
  414.     ' Create polylines parallel to the X axis.
  415.     For z = Zmin To Zmax Step GapZ
  416.         Set pline = New ObjPolyline
  417.         refined.objects.Add pline
  418.         
  419.         x1 = Xmin
  420.         y1 = SurfaceValue(Xmin, z)
  421.         z1 = z
  422.         
  423.         For x = Xmin + Dx To Xmax Step Dx
  424.             y = SurfaceValue(x, z)
  425.             pline.AddSegment x1, y1, z1, x, y, z
  426.             x1 = x
  427.             y1 = y
  428.             z1 = z
  429.         Next x
  430.     Next z
  431.     ' Create polylines parallel to the Z axis.
  432.     For x = Xmin To Xmax Step GapX
  433.         Set pline = New ObjPolyline
  434.         refined.objects.Add pline
  435.         
  436.         x1 = x
  437.         y1 = SurfaceValue(x, Zmin)
  438.         z1 = Zmin
  439.         
  440.         For z = Zmin + Dz To Zmax Step Dz
  441.             y = SurfaceValue(x, z)
  442.             pline.AddSegment x1, y1, z1, x, y, z
  443.             x1 = x
  444.             y1 = y
  445.             z1 = z
  446.         Next z
  447.     Next x
  448. End Sub
  449. Private Sub mnuFileExit_Click()
  450.     Unload Me
  451. End Sub
  452. Private Sub mnuFileLoad_Click()
  453. Dim fname As String
  454. Dim filenum As Integer
  455. Dim txt As String
  456. Dim Xmin As Single
  457. Dim Ymin As Single
  458. Dim Xmax As Single
  459. Dim Ymax As Single
  460.     ' Allow the user to pick a file.
  461.     On Error Resume Next
  462.     LoadDialog.filename = "*.APF"
  463.     LoadDialog.ShowOpen
  464.     If Err.Number = cdlCancel Then
  465.         Unload LoadDialog
  466.         Exit Sub
  467.     ElseIf Err.Number <> 0 Then
  468.         Unload LoadDialog
  469.         Beep
  470.         MsgBox "Error selecting file.", , vbExclamation
  471.         Exit Sub
  472.     End If
  473.     On Error GoTo 0
  474.     MousePointer = vbHourglass
  475.     DoEvents
  476.     fname = LoadDialog.filename
  477.     LoadDialog.InitDir = Left$(fname, Len(fname) _
  478.         - Len(LoadDialog.FileTitle) - 1)
  479.     ' Clear the picture.
  480.     Set ThePicture = Nothing
  481.     ' Open the file.
  482.     filenum = FreeFile
  483.     Open fname For Input As #filenum
  484.     ' Make sure it's an Object Picture File.
  485.     Input #filenum, txt
  486.     If txt <> "3D APF PICTURE" Then
  487.         Close filenum
  488.         Beep
  489.         MsgBox "Error reading file """ & fname & """.", , vbExclamation
  490.         Exit Sub
  491.     End If
  492.     ' Read the picture.
  493.     Set ThePicture = New ObjPicture
  494.     ThePicture.FileInput filenum
  495.     ' Close the file.
  496.     Close filenum
  497.     ' Refresh the display.
  498.     DrawData Pict
  499.     ' Deselect all the option buttons.
  500.     For ChoiceNum = 0 To 8
  501.         If Choice(ChoiceNum).value Then _
  502.             Choice(ChoiceNum).value = False
  503.     Next ChoiceNum
  504.     MousePointer = vbDefault
  505. End Sub
  506. Private Sub mnuFileSaveAs_Click()
  507. Dim fname As String
  508. Dim filenum As Integer
  509.     ' Allow the user to pick a file.
  510.     On Error Resume Next
  511.     LoadDialog.filename = "*.APF"
  512.     LoadDialog.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly
  513.     LoadDialog.ShowSave
  514.     If Err.Number = cdlCancel Then
  515.         Unload LoadDialog
  516.         Exit Sub
  517.     ElseIf Err.Number <> 0 Then
  518.         Unload LoadDialog
  519.         Beep
  520.         MsgBox "Error selecting file.", , vbExclamation
  521.         Exit Sub
  522.     End If
  523.     On Error GoTo 0
  524.     fname = LoadDialog.filename
  525.     LoadDialog.InitDir = Left$(fname, Len(fname) _
  526.         - Len(LoadDialog.FileTitle) - 1)
  527.     ' Open the file.
  528.     filenum = FreeFile
  529.     Open fname For Output As #filenum
  530.     ' Write the picture.
  531.     ThePicture.FileWrite filenum
  532.     ' Close the file.
  533.     Close filenum
  534. End Sub
  535. Private Sub PhiText_Change()
  536.     If ShowingParameters Then Exit Sub
  537.     EyePhi = CSng(PhiText.Text)
  538.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  539.     DrawData Pict
  540. End Sub
  541. Private Sub RText_Change()
  542.     If ShowingParameters Then Exit Sub
  543.     EyeR = CSng(RText.Text)
  544.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  545.     DrawData Pict
  546. End Sub
  547. Private Sub ShowAxesCheck_Click()
  548.     CreateData (ShowAxesCheck.value = vbChecked)
  549.     DrawData Pict
  550.     Pict.SetFocus
  551. End Sub
  552. Private Sub ThetaText_Change()
  553.     If ShowingParameters Then Exit Sub
  554.     EyeTheta = CSng(ThetaText.Text)
  555.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  556.     DrawData Pict
  557. End Sub
  558.